import ctypes
import logging
import keyboard
import time
import random


class YJS:
    def __init__(self, vid="", pid=""):
        self.vid = vid
        self.pid = pid
        self.objdll = None
        self.hdl = None

    # 打开易键鼠
    def open_yjs(self, msdk_path, windows_width, windows_height):
        self.objdll = ctypes.windll.LoadLibrary(msdk_path)
        self.objdll.M_Open_VidPid.restype = ctypes.c_uint64
        self.hdl = self.objdll.M_Open_VidPid(ctypes.c_uint64(int(self.vid, 16)), ctypes.c_uint64(int(self.pid, 16)))

        if self.hdl == ctypes.c_uint64(-1).value:
            logging.error(f"打开盒子失败 vid:{self.vid} pid:{self.pid}")
            self.objdll = None
            self.hdl = None
            return False

        self.objdll.M_ResolutionUsed(ctypes.c_uint64(self.hdl), windows_width, windows_height)
        return True

    # 关闭易键鼠
    def close_yjs(self):
        if not self.objdll or self.hdl is None or self.hdl == ctypes.c_uint64(-1).value:
            logging.warning("易键鼠驱动未加载或未连接，无法执行关闭操作。")
            return

        try:
            self.release_all_key()
            self.objdll.M_Close(ctypes.c_uint64(self.hdl))
            logging.info("易键鼠已安全关闭。")
        except Exception as e:
            logging.error(f"关闭易键鼠时发生错误: {e}")

    # 角色奔跑
    def role_run(self, key):
        if key == keyboard.Right:
            rs1 = self.get_key_state(keyboard.Left)
            if rs1 == 1:
                self.key_up(keyboard.Left)
            elif rs1 == -1:
                logging.info(f"反向按键：{keyboard.key_name_map[keyboard.Left]}状态异常")
        if key == keyboard.Left:
            rs2 = self.get_key_state(keyboard.Right)
            if rs2 == 1:
                self.key_up(keyboard.Right)
            elif rs2 == -1:
                logging.info(f"反向按键：{keyboard.key_name_map[keyboard.Right]}状态异常")
        rs = self.get_key_state(key)
        if rs == 0:
            # 按键操作
            self.objdll.M_KeyDown2(ctypes.c_uint64(self.hdl), key)
            time.sleep(random.uniform(0.05, 0.1))
            self.objdll.M_KeyUp2(ctypes.c_uint64(self.hdl), key)
            time.sleep(random.uniform(0.05, 0.1))
            self.objdll.M_KeyDown2(ctypes.c_uint64(self.hdl), key)
            # logging.info(f"按下{keyboard.key_name_map[key]}键")
        elif rs == -1:
            logging.info(f"{keyboard.key_name_map[key]}键状态异常")

    # 按下按键不设延迟
    def simple_key_down(self, key):
        if key == keyboard.Up:
            rs1 = self.get_key_state(keyboard.Down)
            if rs1 == 1:
                self.key_up(keyboard.Down)
            elif rs1 == -1:
                logging.info(f"反向按键：{keyboard.key_name_map[keyboard.Down]}状态异常")
        if key == keyboard.Down:
            rs2 = self.get_key_state(keyboard.Up)
            if rs2 == 1:
                self.key_up(keyboard.Up)
            elif rs2 == -1:
                logging.info(f"反向按键：{keyboard.key_name_map[keyboard.Up]}状态异常")
        rs = self.get_key_state(key)
        if rs == 0:
            # 按键操作
            self.objdll.M_KeyDown2(ctypes.c_uint64(self.hdl), key)
        elif rs == -1:
            logging.info(f"{keyboard.key_name_map[key]}键状态异常")

    # 按n下按键
    def key_press(self, key, int_nbr=1):
        self.objdll.M_KeyPress2(ctypes.c_uint64(self.hdl), key, int_nbr)
        # logging.info(f"按{int_nbr}次{keyboard.key_name_map[key]}键")

    # 按下按键
    def key_down(self, key):
        if key == keyboard.Up:
            rs1 = self.get_key_state(keyboard.Down)
            if rs1 == 1:
                self.key_up(keyboard.Down)
            elif rs1 == -1:
                logging.info(f"反向按键：{keyboard.key_name_map[keyboard.Down]}状态异常")
        if key == keyboard.Down:
            rs2 = self.get_key_state(keyboard.Up)
            if rs2 == 1:
                self.key_up(keyboard.Up)
            elif rs2 == -1:
                logging.info(f"反向按键：{keyboard.key_name_map[keyboard.Up]}状态异常")
        rs = self.get_key_state(key)
        if rs == 0:
            # 按键操作
            self.objdll.M_KeyDown2(ctypes.c_uint64(self.hdl), key)
            time.sleep(random.uniform(0.01, 0.03))
            # logging.info(f"按下{keyboard.key_name_map[key]}键")
        elif rs == -1:
            logging.info(f"{keyboard.key_name_map[key]}键状态异常")

    # 弹起按键
    def key_up(self, key):
        self.objdll.M_KeyUp2(ctypes.c_uint64(self.hdl), key)
        rs = self.get_key_state(key)
        if rs == 0:
            pass
            # logging.info(f"弹起:{keyboard.key_name_map[key]}键")
        else:
            logging.info(f"{keyboard.key_name_map[key]}键状态异常")

    # 获取按键状态
    def get_key_state(self, key):
        rs = self.objdll.M_KeyState2(ctypes.c_uint64(self.hdl), key)
        if rs == 1:
            return 1
        elif rs == 0:
            return 0
        return -1

    # 弹起所有按键
    def release_all_key(self):
        return self.objdll.M_ReleaseAllKey(ctypes.c_uint64(self.hdl))

    def mouse_move3(self, x, y):
        self.objdll.M_MoveTo3(ctypes.c_uint64(self.hdl), int(x), int(y))
        # logging.info(f"移动鼠标到({x},{y})")

    # 鼠标左键点击
    def mouse_left_click(self, int_nbr=1):
        self.objdll.M_LeftClick(ctypes.c_uint64(self.hdl), int_nbr)
        # logging.info("点击鼠标左键")

    def mouse_right_click(self, int_nbr=1):
        self.objdll.M_RightClick(ctypes.c_uint64(self.hdl), int_nbr)
        # logging.info("点击鼠标右键")

    def mouse_wheel(self, int_nbr=1):
        # int_nbr滚动量 为正，向上滚动，为负，向下滚动
        self.objdll.M_MouseWheel(ctypes.c_uint64(self.hdl), int_nbr)


if __name__ == '__main__':
    VID, PID = "0xC216", "0x0102"
    yjs = YJS(VID, PID)
    yjs.open_yjs("./msdk.dll",1920,1080)
    # 鼠标右键
    # yjs.mouse_right_click()
    yjs.role_run(keyboard.Right)
    yjs.close_yjs()
